home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / c / cxref-1.001 / cxref-1~ / cxref / parse.y < prev    next >
Encoding:
Lex Description  |  1996-02-24  |  26.3 KB  |  1,081 lines

  1. %{
  2. /***************************************
  3.   $Header: /home/amb/cxref/RCS/parse.y 1.12 1996/02/24 14:53:39 amb Exp $
  4.  
  5.   C Cross Referencing & Documentation tool. Version 1.0
  6.  
  7.   C parser.
  8.   ******************/ /******************
  9.   Original Written by N. A. Balharrie
  10.   Actions and hacks Written by Andrew M. Bishop
  11.  
  12.   This file Copyright 1995,96 Andrew M. Bishop
  13.   It may be distributed under the GNU Public License, version 2, or
  14.   any higher version.  See section COPYING of the GNU Public license
  15.   for conditions under which this file may be redistributed.
  16.   ***************************************/
  17.  
  18. #include <string.h>
  19. #include "parse-yy.h"
  20. #include "cxref.h"
  21. #include "memory.h"
  22.  
  23. static void yyerror(char *s);
  24.  
  25. /*+ When in a function header, most of the stuff can be skipped over quickly. +*/
  26. extern int in_header;
  27.  
  28. /*+ A flag that is set to true when typedef is seen in a statement. +*/
  29. int in_typedef=0;
  30.  
  31. /*+ The scope of the function / variable that is being examined. +*/
  32. static int scope;
  33.  
  34. /*+ The variable must be LOCAL or EXTERNAL or GLOBAL, so this checks and sets that. +*/
  35. #define SCOPE ( scope&(LOCAL|EXTERNAL|EXTERN_H) ? scope : scope|GLOBAL )
  36.  
  37. /*+ When in a function or a function definition, the behaviour is different. +*/
  38. int in_function=0,in_funcdef=0;
  39.  
  40. /*+ Some strings that are needed during parsing. +*/
  41. static char *var_name=NULL,*type_name=NULL,*su_type=NULL;
  42.  
  43. /*+ Declarations that are in the same statement share this comment. +*/
  44. static char* common_comment=NULL;
  45.  
  46. /*+ When inside a struct / union / enum defintion, this is the depth. +*/
  47. static int in_structunion=0;
  48.  
  49. /*+ A simple macro that reset all of the variables to the default states. +*/
  50. #define RESET_VARS \
  51.       { \
  52.         scope=0; \
  53.         in_typedef=0; \
  54.         in_structunion=0; \
  55.         var_name=NULL; \
  56.         type_name=NULL; \
  57.         su_type=NULL; \
  58.         common_comment=NULL; \
  59.       }
  60.  
  61. %}
  62.  
  63. %expect 25
  64.  
  65. %token IDENTIFIER LITERAL TYPE_NAME STRING_LITERAL ELLIPSES
  66.  
  67. %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
  68. %token EQ_OP NE_OP PTR_OP AND_OP OR_OP DEC_OP INC_OP LE_OP GE_OP
  69. %token LEFT_SHIFT RIGHT_SHIFT
  70. %token SIZEOF
  71. %token TYPEDEF EXTERN STATIC AUTO REGISTER
  72. %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID INLINE
  73. %token STRUCT UNION ENUM
  74.  
  75. %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
  76.  
  77. %start file
  78.  
  79. %%
  80.  
  81. abstract_declarator
  82.     : pointer
  83.     | pointer direct_abstract_declarator
  84.                 { $$=ConcatStrings(2,$1,$2); }
  85.     | direct_abstract_declarator
  86.     ;
  87.  
  88. add_op
  89.     : '+'
  90.     | '-'
  91.     ;
  92.  
  93. additive_expression
  94.     : multiplicative_expression
  95.     | additive_expression add_op multiplicative_expression
  96.     ;
  97.  
  98. address_expression
  99.     : '&' unary_expression
  100.     ;
  101.  
  102. array_declarator
  103.     : direct_declarator '[' ']'
  104.                 { $$=ConcatStrings(3,$1,$2,$3); }
  105.     | direct_declarator '[' constant_expression ']'
  106.                 { $$=ConcatStrings(4,$1,$2,$3,$4); }
  107.     ;
  108.  
  109. assignment_expression
  110.     : conditional_expression
  111.     | unary_expression assignment_op assignment_expression
  112.     ;
  113.  
  114. assignment_op
  115.         : '='
  116.         | MUL_ASSIGN
  117.         | DIV_ASSIGN
  118.         | MOD_ASSIGN
  119.         | ADD_ASSIGN
  120.         | SUB_ASSIGN
  121.         | LEFT_ASSIGN
  122.         | RIGHT_ASSIGN
  123.         | AND_ASSIGN
  124.         | XOR_ASSIGN
  125.         | OR_ASSIGN
  126.         ;
  127.  
  128. bit_field
  129.     : ':' width
  130.     | declarator ':' width
  131.     ;
  132.  
  133. bitwise_and_expression
  134.     : equality_expression
  135.     | bitwise_and_expression '&' equality_expression
  136.     ;
  137.  
  138. bitwise_negation_expression
  139.     : '~' unary_expression
  140.     ;
  141.  
  142. bitwise_or_expression
  143.     : bitwise_xor_expression
  144.     | bitwise_or_expression '|' bitwise_xor_expression
  145.     ;
  146.  
  147. bitwise_xor_expression
  148.     : bitwise_and_expression
  149.     | bitwise_xor_expression '^' bitwise_and_expression
  150.     ;
  151.  
  152. break_statement
  153.     : BREAK ';'
  154.  
  155. case_label
  156.     : CASE constant_expression
  157.     ;
  158.  
  159. cast_expression
  160.     : '(' type_name ')' unary_expression
  161.     ;
  162.  
  163. character_type_specifier
  164.     : CHAR
  165.     | SIGNED CHAR
  166.                 { $$=ConcatStrings(3,$1," ",$2); }
  167.     | UNSIGNED CHAR
  168.                 { $$=ConcatStrings(3,$1," ",$2); }
  169.     ;
  170.  
  171. comma_expression
  172.     : assignment_expression
  173.     | comma_expression ',' assignment_expression
  174.     ;
  175.  
  176. component_declaration
  177.     : type_specifier { type_name=$1; } component_declarator_list ';'
  178.                 { $$=ConcatStrings(3,$1,$3,$4); }
  179. /* an AMB hack to allow 'const' in a struct component! */
  180.     | type_qualifier_list type_specifier { type_name=ConcatStrings(2,$1,$2); } component_declarator_list ';'
  181.                 { $$=ConcatStrings(4,$1,$2,$3,$4); }
  182.     ;
  183.  
  184. component_declarator
  185.     : simple_component
  186.     | bit_field
  187.     ;
  188.  
  189. component_declarator_list
  190.     : component_declarator
  191.                 { if(!in_header) SeenStructUnionComp(ConcatStrings(2,type_name,$1),in_structunion); }
  192.     | component_declarator_list ',' component_declarator
  193.                 { $$=ConcatStrings(3,$1,$2,$3);
  194.                   if(!in_header) SeenStructUnionComp(ConcatStrings(2,type_name,$3),in_structunion); }
  195.     ;
  196.  
  197. component_selection_expression
  198.     : direct_component_selection
  199.     | indirect_component_selection
  200.     ;
  201.  
  202. /* An AMB Hack to simplify the code, 'compound_statement_body' is a new rule. */
  203. compound_statement
  204.     : '{'
  205.                 { UpScope(); }
  206.       compound_statement_body
  207.                 { DownScope(); }
  208.       '}'
  209.     ;
  210.  
  211. compound_statement_body
  212.     : /* Empty */
  213.     | inner_declaration_list
  214.     | statement_list
  215.     | inner_declaration_list statement_list
  216.     ;
  217.  
  218. conditional_expression
  219.     : logical_or_expression
  220.     | logical_or_expression '?' expression ':' conditional_expression
  221.     ;
  222.  
  223. conditional_statement
  224.     : if_statement
  225.     | if_else_statement
  226.     ;
  227.  
  228. constant_expression
  229.     : expression
  230.     ;
  231.  
  232. continue_statement
  233.     : CONTINUE ';'
  234.     ;
  235.  
  236. declaration
  237.     : declaration_specifiers initialized_declarator_list ';'
  238. /* an AMB hack to allow 'union name { ... };' */
  239.     | declaration_specifiers ';'
  240.     ;
  241.  
  242. declaration_list
  243.     : declaration
  244.     | declaration_list declaration
  245.                 { $$=$2; }
  246.     ;
  247.  
  248. declaration_specifiers
  249.         : declaration_specifiers1
  250.                 { if(!in_typedef) {common_comment=GetCurrentComment(); SetCurrentComment(common_comment);} }
  251.     ;
  252.  
  253. declaration_specifiers1
  254.     : storage_class_specifier
  255.     | storage_class_specifier declaration_specifiers1
  256.                 { if($1) $$=ConcatStrings(3,$1," ",$2); else $$=$2; }
  257.     | type_specifier
  258.                 { type_name=$1; }
  259.     | type_specifier declaration_specifiers1
  260.                 { $$=ConcatStrings(3,$1," ",$2); }
  261.     | type_qualifier
  262.     | type_qualifier declaration_specifiers1
  263.                 { $$=ConcatStrings(3,$1," ",$2); }
  264.     ;
  265.  
  266. declarator
  267.     : direct_declarator
  268.     | pointer direct_declarator
  269.                 { $$=ConcatStrings(2,$1,$2); }
  270.     ;
  271.  
  272. default_label
  273.     : DEFAULT
  274.     ;
  275.  
  276. direct_abstract_declarator
  277.     : '(' abstract_declarator ')'
  278.                 { $$=ConcatStrings(3,$1,$2,$3); }
  279.     | '[' ']'
  280.                 { $$=ConcatStrings(2,$1,$2); }
  281.     | direct_abstract_declarator '[' ']'
  282.                 { $$=ConcatStrings(3,$1,$2,$3); }
  283.     | '[' constant_expression ']'
  284.                 { $$=ConcatStrings(3,$1,$2,$3); }
  285.     | direct_abstract_declarator '[' constant_expression ']'
  286.                 { $$=ConcatStrings(4,$1,$2,$3,$4); }
  287.     | '(' ')'
  288.                 { $$=ConcatStrings(2,$1,$2); }
  289.     | direct_abstract_declarator '(' ')'
  290.                 { $$=ConcatStrings(3,$1,$2,$3); }
  291.     | '(' parameter_type_list ')'
  292.                 { $$=ConcatStrings(3,$1,$2,$3); }
  293.     | direct_abstract_declarator '(' parameter_type_list ')'
  294.                 { $$=ConcatStrings(4,$1,$2,$3,$4); }
  295.     ;
  296.  
  297. direct_component_selection
  298.     : postfix_expression '.' name
  299.     ;
  300.  
  301. direct_declarator
  302.     : simple_declarator
  303.     | '(' declarator ')'
  304.                 { if($2[0]=='*' && $2[1]==' ') { $2=&$2[1]; $2[0]='*'; }
  305.                   $$=ConcatStrings(4," ",$1,$2,$3);
  306.                 }
  307.     | array_declarator
  308.     | function_declarator
  309.     ;
  310.  
  311. do_statement
  312.     : DO statement WHILE '(' expression ')' ';'
  313.     ;
  314.  
  315. enumeration_constant
  316.     : IDENTIFIER
  317.     ;
  318.  
  319. enumeration_constant_definition
  320.     : enumeration_constant
  321.                 { if(!in_header) SeenStructUnionComp($1,in_structunion); }
  322. /* an AMB Hack, was '... = expression' but this does not parse 'int a=0,b=1,c;' (confuses it as a comma_expression) */
  323.     | enumeration_constant '=' assignment_expression
  324.                 { $$=ConcatStrings(3,$1,$2,$3); if(!in_header) SeenStructUnionComp($1,in_structunion); }
  325.     ;
  326.  
  327. enumeration_definition_list
  328.     : enumeration_constant_definition
  329.     | enumeration_definition_list ',' enumeration_constant_definition
  330.                 { $$=ConcatStrings(3,$1,$2,$3); }
  331.     ;
  332.  
  333. enumeration_tag
  334.     : IDENTIFIER
  335.     ;
  336.  
  337. enumeration_type_definition
  338.     : ENUM '{'
  339.                 { if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
  340.                   if(!in_header)
  341.                     {
  342.                      if(in_structunion) SeenStructUnionComp($1,in_structunion);
  343.                      else               SeenStructUnionStart($1);
  344.                     }
  345.                   in_structunion++; }
  346.           enumeration_definition_list '}'
  347.                 { in_structunion--;
  348.                   if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
  349.                   $$=ConcatStrings(5,$1," ",$2,$4,$5); }
  350.     | ENUM enumeration_tag '{'
  351.                 { if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
  352.                   if(!in_header)
  353.                     {
  354.                      if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
  355.                      else               SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
  356.                     }
  357.                   in_structunion++; }
  358.           enumeration_definition_list '}'
  359.                 { in_structunion--;
  360.                   if(!in_header && !in_structunion) SeenStructUnionEnd();
  361.                   $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
  362.     ;
  363.  
  364. enumeration_type_reference
  365.     : ENUM enumeration_tag
  366.                 { $$=ConcatStrings(3,$1," ",$2); }
  367.     ;
  368.  
  369. enumeration_type_specifier
  370.     : enumeration_type_definition
  371.     | enumeration_type_reference
  372.     ;
  373.  
  374. equality_expression
  375.     : relational_expression
  376.     | equality_expression equality_op relational_expression
  377.     ;
  378.  
  379. equality_op
  380.     : EQ_OP
  381.     | NE_OP
  382.     ;
  383.  
  384. expression
  385.     : comma_expression
  386.     ;
  387.  
  388. expression_list
  389.     : assignment_expression
  390.     | expression_list ',' assignment_expression
  391.     ;
  392.  
  393. expression_statement
  394.     : expression ';'
  395.     ;
  396.  
  397. field_list
  398.     : component_declaration
  399.     | field_list component_declaration
  400.                 { $$=ConcatStrings(2,$1,$2); }
  401.     ;
  402.  
  403. /* AMB Hack to cope with an empty file */
  404. file
  405.     : /* Empty */
  406.     | program
  407.     ;
  408.  
  409. floating_type_specifier
  410.     : FLOAT
  411.     | DOUBLE
  412.     | LONG DOUBLE
  413.                 { $$=ConcatStrings(3,$1," ",$2); }
  414.     ;
  415.  
  416. for_expressions
  417.     : ';' ';'
  418.     | expression ';' ';'
  419.     | ';' expression ';'
  420.     | ';' ';' expression
  421.     | ';' expression ';' expression
  422.     | expression ';' ';' expression
  423.     | expression ';' expression ';'
  424.     | expression ';' expression ';' expression
  425.     ;
  426.  
  427. for_statement
  428.     : FOR '(' for_expressions ')' statement
  429.     ;
  430.  
  431. function_call
  432.     : postfix_expression '(' ')'
  433.     | postfix_expression '(' expression_list ')'
  434.     ;
  435.  
  436. /* An AMB hack, function_call_direct is entirely of my invention to avoid pointer to function */
  437. function_call_direct
  438.     : name '(' ')'
  439.     | name '(' expression_list ')'
  440.     ;
  441.  
  442. function_declarator
  443.     : function_declarator1 '(' function_declarator2 ')'
  444.                { $$=ConcatStrings(4,$1,$2,$3,$4);
  445.                  if(in_funcdef>1) in_funcdef--; }
  446.     ;
  447.  
  448. /* an AMB hack to simplify the code , taken function_declarator1 out of function_declarator */
  449. function_declarator1
  450.     : direct_declarator
  451.                 { if(!in_funcdef)
  452.                     {
  453.                      if(!in_typedef && !in_function && !in_header)
  454.                         SeenFunctionDeclaration(var_name,SCOPE);
  455.                      if(!in_function) UpScope();
  456.                     }
  457.                   if(!in_structunion)
  458.                      in_funcdef++;
  459.                 }
  460.     ;
  461.  
  462. /* an AMB hack to simplify the code , taken function_declarator2 out of function_declarator */
  463. function_declarator2
  464.     : /* Empty */ { $$=NULL; }
  465.     | parameter_type_list
  466.     | identifier_list
  467.     ;
  468.  
  469. function_definition
  470.     : function_specifier1
  471.                 { in_function=1; in_funcdef=0; }
  472.           compound_statement
  473.                 { in_function=0; DownScope(); }
  474.     ;
  475.  
  476. /* An AMB Hack to simplify the parse tree */
  477. function_specifier1
  478.     : function_specifier
  479.                 { if(!in_header)
  480.                      {
  481.                       char *func_type,*vname=strstr($1,var_name),*pareth=strstr($1,"(");
  482.                       if(pareth>vname)
  483.                          {func_type=$1;pareth[0]=0;}
  484.                       else
  485.                         {
  486.                          int open=1;
  487.                          char *argbeg=strstr(&pareth[1],"("),*argend;
  488.                          argbeg[1]=0;
  489.                          for(argend=argbeg+2;*argend;argend++)
  490.                            {
  491.                             if(*argend=='(') open++;
  492.                             if(*argend==')') open--;
  493.                             if(!open) break;
  494.                            }
  495.                          func_type=ConcatStrings(2,$1,argend);
  496.                         }
  497.                       SeenFunctionDefinition(func_type);
  498.                      }
  499.                 }
  500.     ;
  501.  
  502. function_specifier
  503.     : declarator
  504.     | declaration_specifiers declarator
  505.                 { $$=ConcatStrings(2,$1,$2); }
  506.     | declarator { in_function=2; } declaration_list
  507.     | declaration_specifiers declarator { in_function=2; } declaration_list
  508.                 { $$=ConcatStrings(2,$1,$2); }
  509.     ;
  510.  
  511. goto_statement
  512.     : GOTO IDENTIFIER ';'
  513.     ;
  514.  
  515. identifier_list
  516.     : IDENTIFIER
  517.     | identifier_list ',' IDENTIFIER
  518.                 { $$=ConcatStrings(3,$1,$2,$3); }
  519.     ;
  520.  
  521. if_else_statement
  522.     : IF '(' expression ')' statement ELSE statement
  523.     ;
  524.  
  525. if_statement
  526.     : IF '(' expression ')' statement
  527.     ;
  528.  
  529. indirect_component_selection
  530.     : postfix_expression PTR_OP name
  531.     ;
  532.  
  533. indirection_expression
  534.     : '*' unary_expression
  535.     ;
  536.  
  537. /* an AMB hack to allow simplification of the code , put initialized_declarator1 in initialized_declarator_list */
  538. initialized_declarator1
  539.     : initialized_declarator
  540.                 {
  541.                  if(!in_function && !in_funcdef && !in_structunion)
  542.                    {
  543.                     char* specific_comment=GetCurrentComment();
  544.                     if(!common_comment)   SetCurrentComment(specific_comment); else
  545.                     if(!specific_comment) SetCurrentComment(common_comment);   else
  546.                     if(common_comment!=specific_comment) SetCurrentComment(ConcatStrings(3,common_comment," ",specific_comment)); else
  547.                                           SetCurrentComment(common_comment);
  548.                    }
  549.  
  550.                   if(in_typedef)
  551.                     {
  552.                      SeenTypedefName(var_name);
  553.                      if(!in_header)
  554.                         SeenTypedef(var_name,ConcatStrings(2,su_type?su_type:type_name,$1));
  555.                     }
  556.                   else
  557.                      if(in_function==2 && in_funcdef)
  558.                        { SeenFunctionArg(ConcatStrings(2,type_name,$1)); SeenScopeVariable(var_name); }
  559.                      else
  560.                         if(in_function)
  561.                            SeenScopeVariable(var_name);
  562.                         else
  563.                           {
  564.                            char* vname=strstr($1,var_name);
  565.                            if(vname[strlen(var_name)]=='(')
  566.                               SeenFunctionProto(var_name);
  567.                            else
  568.                               if(!in_structunion && (!in_header || ((in_header==LOCAL)&&(scope&EXTERN_H))))
  569.                                  SeenVariableDefinition(var_name,ConcatStrings(2,type_name,$1),SCOPE);
  570.                           }
  571.  
  572.                  if(in_funcdef && in_function!=2) { in_funcdef=0; if(!in_function) DownScope(); }
  573.                 }
  574.     ;
  575.  
  576. initialized_declarator
  577.     : declarator
  578.     | declarator initializer_part
  579.     ;
  580.  
  581. initialized_declarator_list
  582.     : initialized_declarator1
  583.     | initialized_declarator_list ',' initialized_declarator1
  584.     ;
  585.  
  586. initializer
  587. /* an AMB Hack, was ': expression' but this does not parse 'int a=0,b;' (confuses it as a comma_expression) */
  588.     : assignment_expression
  589.     | '{' initializer_list '}'
  590.     | '{' initializer_list ',' '}'
  591.     ;
  592.  
  593. initializer_list
  594.     : initializer
  595.     | initializer_list ',' initializer
  596.     ;
  597.  
  598. initializer_part
  599.     : '=' initializer
  600.     ;
  601.  
  602. inner_declaration_list
  603.     : declaration_list
  604.     ;
  605.  
  606. integer_type_specifier
  607.     : signed_type_specifier
  608.     | unsigned_type_specifier
  609.     | character_type_specifier
  610.     ;
  611.  
  612. iterative_statement
  613.     : do_statement
  614.     | while_statement
  615.     | for_statement
  616.     ;
  617.  
  618. label
  619.     : named_label
  620.     | case_label
  621.     | default_label
  622.     ;
  623.  
  624. labeled_statement
  625.     : label ':' statement
  626.  
  627. logical_and_expression
  628.     : bitwise_or_expression
  629.     | logical_and_expression AND_OP bitwise_or_expression
  630.     ;
  631.  
  632. logical_negation_expression
  633.     : '!' unary_expression
  634.     ;
  635.  
  636. logical_or_expression
  637.     : logical_and_expression
  638.     | logical_or_expression OR_OP logical_and_expression
  639.     ;
  640.  
  641. mult_op
  642.     : '*'
  643.     | '/'
  644.     | '%'
  645.     ;
  646.  
  647. multiplicative_expression
  648.     : unary_expression
  649.     | multiplicative_expression mult_op unary_expression
  650.     ;
  651.  
  652. name
  653.     : IDENTIFIER
  654.     ;
  655.  
  656. named_label
  657.     : IDENTIFIER
  658.     ;
  659.  
  660. null_statement
  661.     : ';'
  662.     ;
  663.  
  664. parameter_declaration
  665.     : declaration_specifiers declarator
  666.                 { $$=ConcatStrings(2,$1,$2); }
  667.     | declaration_specifiers
  668.     | declaration_specifiers abstract_declarator
  669.                 { $$=ConcatStrings(2,$1,$2); }
  670.     ;
  671.  
  672. parameter_list
  673.     : parameter_declaration
  674.                 { if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($1); }
  675.     | parameter_list ',' parameter_declaration
  676.                 { if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($3);
  677.                   $$=ConcatStrings(3,$1,$2,$3); }
  678.     ;
  679.  
  680. parameter_type_list
  681.     : parameter_list
  682.     | parameter_list ',' ELLIPSES
  683.                 { if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($3);
  684.                   $$=ConcatStrings(3,$1,$2,$3); }
  685.     ;
  686.  
  687. parenthesized_expression
  688.     : '(' expression ')'
  689.     ;
  690.  
  691. pointer
  692.     : '*'
  693.     | '*' pointer1
  694.                 { $$=ConcatStrings(2,$1,$2); }
  695.     ;
  696.  
  697. pointer1
  698.     : type_qualifier_list
  699.     | pointer
  700.     | type_qualifier_list pointer
  701.                 { $$=ConcatStrings(2,$1,$2); }
  702.     ;
  703.  
  704. postdecrement_expression
  705.     : postfix_expression DEC_OP
  706.     ;
  707.  
  708. postfix_expression
  709.     : primary_expression
  710.     | subscript_expression
  711.     | component_selection_expression
  712.     | function_call
  713.     | function_call_direct
  714.                 { if(!in_header && !IsAScopeVariable($1)) SeenFunctionCall($1); }
  715.     | postincrement_expression
  716.     | postdecrement_expression
  717.     ;
  718.  
  719. postincrement_expression
  720.     : postfix_expression INC_OP
  721.     ;
  722.  
  723. predecrement_expression
  724.     : DEC_OP unary_expression
  725.     ;
  726.  
  727. preincrement_expression
  728.     : INC_OP unary_expression
  729.     ;
  730.  
  731. primary_expression
  732.     : name
  733.                 { if(!in_header) CheckFunctionVariableRef($1,in_function); }
  734.     | LITERAL
  735.     | string_literal
  736.     | parenthesized_expression
  737.     ;
  738.  
  739. program
  740.     : top_level_declaration
  741.     | program top_level_declaration
  742.     ;
  743.  
  744. relational_expression
  745.     : shift_expression
  746.     | relational_expression relational_op shift_expression
  747.     ;
  748.  
  749. relational_op
  750.     : '<'
  751.     | LE_OP
  752.     | '>'
  753.     | GE_OP
  754.     ;
  755.  
  756. return_statement
  757.     : RETURN ';'
  758.     | RETURN expression ';'
  759.     ;
  760.  
  761. shift_expression
  762.     : additive_expression
  763.     | shift_expression shift_op additive_expression
  764.     ;
  765.  
  766. shift_op
  767.     : LEFT_SHIFT
  768.     | RIGHT_SHIFT
  769.     ;
  770.  
  771. signed_type_specifier
  772.     : SHORT
  773.     | SHORT INT
  774.                 { $$=ConcatStrings(3,$1," ",$2); }
  775.     | INT
  776.     | LONG
  777.     | LONG INT
  778.                 { $$=ConcatStrings(3,$1," ",$2); }
  779.     | LONG LONG
  780.                 { $$=ConcatStrings(3,$1," ",$2); }
  781.     | SIGNED
  782.     | SIGNED SHORT
  783.                 { $$=ConcatStrings(3,$1," ",$2); }
  784.     | SIGNED SHORT INT
  785.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  786.     | SIGNED INT
  787.                 { $$=ConcatStrings(3,$1," ",$2); }
  788.     | SIGNED LONG
  789.                 { $$=ConcatStrings(3,$1," ",$2); }
  790.     | SIGNED LONG INT
  791.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  792.     | SIGNED LONG LONG
  793.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  794.     ;
  795.  
  796. simple_component
  797.     : declarator
  798.     ;
  799.  
  800. simple_declarator
  801.     : IDENTIFIER
  802.                 { $$=ConcatStrings(2," ",$1); if(!in_funcdef) var_name=$1; else SeenScopeVariable($1); }
  803.     ;
  804.  
  805. sizeof_expression
  806.     : SIZEOF '(' type_name ')'
  807.     | SIZEOF unary_expression
  808.     ;
  809.  
  810. statement
  811.     : expression_statement
  812.     | labeled_statement
  813.     | compound_statement
  814.     | conditional_statement
  815.     | iterative_statement
  816.     | switch_statement
  817.     | break_statement
  818.     | continue_statement
  819.     | return_statement
  820.     | goto_statement
  821.     | null_statement
  822.     ;
  823.  
  824. statement_list
  825.     : statement
  826.     | statement_list statement
  827.     ;
  828.  
  829. storage_class_specifier
  830.     : AUTO
  831.                 { $$=NULL; }
  832.     | EXTERN
  833.                 { $$=NULL; if(in_header) scope |= EXTERN_H; else scope |= EXTERNAL; }
  834.     | REGISTER
  835.                 { $$=NULL; }
  836.     | STATIC
  837.                 { $$=NULL; scope |= LOCAL; }
  838.     | TYPEDEF
  839.                 { in_typedef=1; if(!in_header) SeenTypedef(NULL,NULL);
  840.                   common_comment=GetCurrentComment(); SetCurrentComment(common_comment); }
  841. /* an AMB hack to allow inline functions */
  842.     | INLINE
  843.                 { $$=NULL; scope |= INLINED; }
  844.     ;
  845.  
  846. string_literal
  847.     : STRING_LITERAL
  848. /* an AMB hack to allow '"foo" "bar"' to be recognised as "foobar"  */
  849.     | string_literal STRING_LITERAL
  850.         ;
  851.  
  852. structure_tag
  853.     : IDENTIFIER
  854. /* an AMB hack to allow 'typedef struct foo foo ; typedef struct foo bar'  */
  855.     | TYPE_NAME
  856.     ;
  857.  
  858. structure_type_definition
  859.     : STRUCT '{'
  860.                 { if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
  861.                   if(!in_header)
  862.                     {
  863.                      if(in_structunion) SeenStructUnionComp($1,in_structunion);
  864.                      else               SeenStructUnionStart($1);
  865.                     }
  866.                   in_structunion++; }
  867.     field_list '}'
  868.                 { in_structunion--;
  869.                   if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
  870.                   $$=ConcatStrings(5,$1," ",$2,$4,$5); }
  871.     | STRUCT structure_tag '{'
  872.                 { if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
  873.                   if(!in_header)
  874.                     {
  875.                      if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
  876.                      else               SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
  877.                     }
  878.                   in_structunion++; }
  879.     field_list '}'
  880.                 { in_structunion--;
  881.                   if(!in_header && !in_structunion) SeenStructUnionEnd();
  882.                   $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
  883.     ;
  884.  
  885. structure_type_reference
  886.     : STRUCT structure_tag
  887.                 { $$=ConcatStrings(3,$1," ",$2); }
  888.     ;
  889.  
  890. structure_type_specifier
  891.     : structure_type_definition
  892.     | structure_type_reference
  893.     ;
  894.  
  895. subscript_expression
  896.     : postfix_expression '[' expression ']'
  897.     ;
  898.  
  899. switch_statement
  900.     : SWITCH '(' expression ')' statement
  901.     ;
  902.  
  903. top_level_declaration
  904.     : declaration
  905.                 { RESET_VARS }
  906.     | function_definition
  907.                 { RESET_VARS }
  908.     ;
  909.  
  910. type_name
  911.     : declaration_specifiers
  912.     | declaration_specifiers abstract_declarator
  913.                 { $$=ConcatStrings(2,$1,$2); }
  914.     ;
  915.  
  916. type_qualifier
  917.     : CONST
  918.                 { $$=ConcatStrings(2,$1," "); }
  919.     | VOLATILE
  920.                 { $$=ConcatStrings(2,$1," "); }
  921.     ;
  922.  
  923. type_qualifier_list
  924.     : type_qualifier
  925.     | type_qualifier_list type_qualifier
  926.                 { $$=ConcatStrings(2,$1,$2); }
  927.     ;
  928.  
  929. type_specifier
  930.     : enumeration_type_specifier
  931.     | floating_type_specifier
  932.     | integer_type_specifier
  933.     | structure_type_specifier
  934.     | typedef_name
  935.     | union_type_specifier
  936.     | void_type_specifier
  937.     ;
  938.  
  939. typedef_name
  940.     : TYPE_NAME
  941.     ;
  942.  
  943. unary_expression
  944.     : postfix_expression
  945.     | cast_expression
  946.     | sizeof_expression
  947.     | unary_minus_expression
  948.     | unary_plus_expression
  949.     | logical_negation_expression
  950.     | bitwise_negation_expression
  951.     | address_expression
  952.     | indirection_expression
  953.     | preincrement_expression
  954.     | predecrement_expression
  955.     ;
  956.  
  957. unary_minus_expression
  958.     : '-' unary_expression
  959.     ;
  960.  
  961. unary_plus_expression
  962.     : '+' unary_expression
  963.     ;
  964.  
  965. union_tag
  966.     : IDENTIFIER
  967. /* an AMB hack to allow 'typedef union foo foo ; typedef union foo bar'  */
  968.     | TYPE_NAME
  969.     ;
  970.  
  971. union_type_definition
  972.     : UNION '{'
  973.                 { if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
  974.                   if(!in_header)
  975.                     {
  976.                      if(in_structunion) SeenStructUnionComp($1,in_structunion);
  977.                      else               SeenStructUnionStart($1);
  978.                     }
  979.                   in_structunion++; }
  980.     field_list '}'
  981.                 { in_structunion--;
  982.                   if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
  983.                   $$=ConcatStrings(5,$1," ",$2,$4,$5); }
  984.     | UNION union_tag '{'
  985.                 { if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
  986.                   if(!in_header)
  987.                     {
  988.                      if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
  989.                      else               SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
  990.                     }
  991.                   in_structunion++; }
  992.     field_list '}'
  993.                 { in_structunion--;
  994.                   if(!in_header && !in_structunion) SeenStructUnionEnd();
  995.                   $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
  996.     ;
  997.  
  998. union_type_reference
  999.     : UNION union_tag
  1000.                 { $$=ConcatStrings(3,$1," ",$2); }
  1001.     ;
  1002.  
  1003. union_type_specifier
  1004.     : union_type_definition
  1005.     | union_type_reference
  1006.     ;
  1007.  
  1008. unsigned_type_specifier
  1009.     : UNSIGNED SHORT INT
  1010.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  1011.     | UNSIGNED INT
  1012.                 { $$=ConcatStrings(3,$1," ",$2); }
  1013.     | UNSIGNED LONG INT
  1014.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  1015.     | UNSIGNED SHORT
  1016.                 { $$=ConcatStrings(3,$1," ",$2); }
  1017.     | UNSIGNED
  1018.     | UNSIGNED LONG
  1019.                 { $$=ConcatStrings(3,$1," ",$2); }
  1020.     | UNSIGNED LONG LONG
  1021.                 { $$=ConcatStrings(5,$1," ",$2," ",$3); }
  1022.     ;
  1023.  
  1024. void_type_specifier
  1025.     : VOID
  1026.     ;
  1027.  
  1028. while_statement
  1029.     : WHILE '(' expression ')' statement
  1030.     ;
  1031.  
  1032. width
  1033.     : expression
  1034.     ;
  1035.  
  1036. %%
  1037.  
  1038. #include <stdio.h>
  1039.  
  1040. static void yyerror( char *s )
  1041. {
  1042.  int i;
  1043.  
  1044.  fflush(stdout);
  1045.  fprintf(stderr,"cxref: Error parsing %s\n\n",s);
  1046.  
  1047. #ifdef YYDEBUG
  1048.  
  1049. /*
  1050.  fprintf(stderr,"in_function=%2d, in_funcdef=%2d\n",in_function,in_funcdef);
  1051.  fprintf(stderr,"var_name='%s'\n",var_name);
  1052.  fprintf(stderr,"in_typedef=%2d,  in_structunion=%2d type_name='%s' su_type='%s'\n",in_typedef,in_structunion,type_name,su_type);
  1053. */
  1054.  
  1055.  fprintf(stderr,"\nThe current and next 10 symbols are:\n");
  1056.  
  1057. #ifdef YYBISON
  1058.  fprintf(stderr,"%3d : %16s : %s\n",yychar,yychar>255?yytname[yychar-255]:"",yylval);
  1059.  for(i=0;i<10;i++)
  1060.    {
  1061.     int yyl=yylex();
  1062.     if(!yyl)
  1063.       {fprintf(stderr,"END OF FILE\n");break;}
  1064.     fprintf(stderr,"%3d : %16s : %s\n",yyl,yyl>255?yytname[yyl-255]:"",yylval);
  1065.    }
  1066. #else
  1067.  fprintf(stderr,"%3d : %s\n",yychar,yylval);
  1068.  for(i=0;i<10;i++)
  1069.    {
  1070.     int yyl=yylex();
  1071.     if(!yyl)
  1072.       {fprintf(stderr,"END OF FILE\n");break;}
  1073.     fprintf(stderr,"%3d : %s\n",yyl,yylval);
  1074.    }
  1075. #endif
  1076.  
  1077. #endif
  1078.  
  1079.  exit(2);
  1080. }
  1081.